# 这是从你那copy过来的传感器相关的函数
import smbus
#import serial
import time
from utils import get_global_value

# 这里为流量传感器的读取函数，涉及到树莓派IIC协议的用法
def read_flow_num(bus, address, base=98):
    # 树莓派IIC协议读数据
    gas_flow = str(bus.read_byte_data(address,0))

    # 这里是因为传感器在无吹气情况下有base输出值，需要减去
    gas_flow_num = int(gas_flow) - base

    return gas_flow_num

# 呼吸频率计算
def time_and_rate(ft, starttime, rate_group):
    endtime = time.time()
    if ft > 0:
        gap_time = endtime - starttime
        print("第" + str(ft) + "次呼吸时间：")
        print(gap_time)
        RR = 60 / (gap_time)
        print("呼吸频率（RR（次/分钟）：")
        print(RR)
        # 添加呼气频率组
        rate_group.append(RR)

# 呼吸参数计算
def calculate(breath, result_send):
    n = len(breath)
    FEV1 = 0
    FVC = 0
    ratio = 0
    for i in range(0,n-1):
        FVC += (breath[i] + breath[i + 1]) * 0.25 * 1000 / 120
    if n >= 4:
        for i in range(0, 3):
            FEV1 += (breath[i] + breath[i + 1]) * 0.25 * 1000 / 120
            ratio = FEV1/FVC
    

    peak_gas_flow = max(breath)

    result_send[0].append(FEV1)
    result_send[1].append(FVC)
    result_send[2].append(ratio)
    result_send[3].append(peak_gas_flow)

    return FEV1, FVC, ratio, peak_gas_flow

# def estimate(sex, year, high):
#   #以年龄和身高预测肺活量VC
#   if sex == 0:
#     VC_woman = (21.78 - 0.101 * year * high)  # 女：VC(ml)=[21.78-0.101*年龄（岁）]*身高(cm)
#     return VC_woman
#   elif sex == 1:
#     VC_man = (27.63-0.112*year)*high#男：VC(ml)=[27.63-0.112*年龄（岁）]*身高(cm)
#     return VC_man

# def calculate_TV(breath):
#   #潮气量TV为平静呼吸中每次吸入或呼出的气量。表示在不施加额外力时，肺正常吸气和呼气时肺移位的正常空气体积。
#   #?潮气量参考值为每次吸气500ml或8-10ml/kg.
#   #每分钟吸入和呼出的气体总量大约为500ml.
#   n = len(breath)
#   for i in range(0,n-1):
#       TV += breath[i] *0.05


# 更新发送的传感器数据数组，长度固定，滚动更新
def updata_breath_send(send_data, new_data, limit=25):
  if len(send_data) > limit:
    del(send_data[0])
    send_data.append(new_data)
  else:
    send_data.append(new_data)


# socket发送实时传感器数据
async def socket_send_realTime_data(websocket, send_data, new_data):
  updata_breath_send(send_data, new_data)
  str_send_data = 'flow:' + ','.join(str(i) for i in send_data)
  await websocket.send(str_send_data)


# socket发送各指标数据集（训练结果）
async def socket_send_result_data(websocket, send_data):
  str_send_data = 'result:'
  for i in range(0, len(send_data)):
    element_str = ','.join(str(i) for i in send_data[i])
    str_send_data = str_send_data + element_str + '|'
  await websocket.send(str_send_data)


# 训练相关的主逻辑，重点！！！
# 包含传感器数据采集、数据处理、数据上传三大逻辑
async def reader_main(websocket):
  
  # 初始化
  bus = smbus.SMBus(1)
  address = 0x50
  breath = []
  breath_group = []
  breath_send = []
  starttime = 0
  ft = 0
  # 添加呼气频率
  rate_group = []
  # 指标数据集，对应5个指标
  result_send = [[], [], [], []]

  # 标定一下起始值
  zero_value = read_flow_num(bus, address, 0)

  # 注意这里是根据全局status标记控制的while循环，是由上位机来控制是否循环状态的
  while get_global_value('status'):
    gas_flow_num = read_flow_num(bus, address, zero_value)

    await socket_send_realTime_data(websocket, breath_send, gas_flow_num)

    time.sleep(0.4)    

    if gas_flow_num != 0:
      #呼吸时间与呼吸频率
      time_and_rate(ft, starttime, rate_group)
      ft += 1
      starttime = time.time()
      #生成瞬时流速采集列表
      while gas_flow_num != 0:
        breath.append(gas_flow_num)
        # press.append(gas_press_num)
        gas_flow_num = read_flow_num(bus, address, zero_value)

        await socket_send_realTime_data(websocket, breath_send, gas_flow_num)
        time.sleep(0.2)

      print(breath)
      #计算FVC、FEV1、PEF值并绘制瞬时呼气流量表
      if len(breath) > 3:
        FEV1, FVC, ratio, peak_gas_flow = calculate(breath, result_send)
        string_FEV1 = "第一秒用力呼气容积（FEV1）:" + str(FEV1)
        print(string_FEV1)
        string_FVC = "用力肺活量（FVC）:" + str(FVC)
        print(string_FVC)
        string_FEV1_FVC = "FEV1/FVC:" + str(ratio)
        print(string_FEV1_FVC)
        string_PEF = "峰流速值（PEF）:" + str(peak_gas_flow)
        print(string_PEF)
        
        breath = []
        breath_group.append(breath)
      elif len(breath) > 0 and len(breath) <4:
        print("呼气无效，请重新呼气")
        breath = []
  
  # 跳出循环后发送结果数据
  if len(result_send[0]) > 0:
    result_send.append(rate_group)
    print(result_send)
    await socket_send_result_data(websocket, result_send)